KLAD API 参考
前言
KLAD是密钥管理模块,集成密钥派生、明文KEY传递、ROOTKEY层级传递。
本文档(本指南)主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
概述
概述
KLAD是密钥管理模块。支持密钥派生、明文KEY传递和ROOTKEY层级传递。支持16个KLAD软件通道。
密钥派生
用户可根据不同的应用场景生成不同的密钥,最多可以派生232个ROOTKEY。
密钥派生出的 work key 可通过提供的派生工具计算,使用方法请参考 “密钥派生工具说明”。
明文KEY传递
明文KEY即加解密引擎使用的工作密钥由用户妥善保存。
- 支持 AES 128/192/256bits加解密。
- 支持 SM4 128bits加解密。
- Hi3403V100、SS626V100不支持 SM4。
ROOTKEY传递
ROOTKEY即通过OTP模块的根密钥,经密钥解混淆、密钥派生后产生的KEY。ROOTKEY存储在硬件中,用户不可读取。加解密的工作密钥是KLAD多次层级传递后得到的KEY,该KEY也是存储在硬件中,用户不可读取。该方案多用于安全要求较高的场景,OTP的根密钥由用户妥善保存。
- 支持 AES 128/256bits加解密。
- 支持 SM4 128bits加解密。
- Hi3403V100、SS626V100不支持 SM4。
- Hi3403V100、SS626V100支持2级KLAD传递。
KLAD使用注意事项
KLAD部署在不同场景下时,使用方式可能会有所不同。
-
在Linux环境下
- 用户态使用KLAD可以通过链接静态库libss_klad.a或动态库libss_klad.so的方式,依赖libsecurec.a或libsecurec.so。
- 内核态KLAD使用模块插入方式,即insmod ot_klad.ko,需要依赖ot_osal.ko,ot_base.ko,sys_config.ko,ot_sys.ko。
-
在OPTEE环境下
- 用户态调用KLAD对外接口,由Linux环境下的ss_mpi_xxx命名形式更改为ot_tee_xxx;
- 内核态调用KLAD对外接口,由Linux环境下的ss_mpi_xxx命名形式更改为ot_drv_xxx。
-
在UBOOT环境下,用户态调用KLAD对外接口由Linux环境下的ss_mpi_xxx命名形式变更为ot_mpi_xxx。
使用流程
明文KEY传递
场景说明
当用于加解密的工作密钥由用户自己传入时,需使用明文KEY相关的接口。KLAD将工作密钥传递给一个KEYSLOT。加解密时,加解密引擎取对应KEYSLOT中的KEY用于加解密。
工作流程
明文KEY传递开发操作步骤如下:
- KLAD设备初始化。调用接口ss_mpi_klad_init。
- 创建KLAD句柄。调用接口ss_mpi_klad_create。
- 绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_attach。
- 设置KLAD属性。调用接口ss_mpi_klad_set_attr。
- 设置明文KEY。调用接口ss_mpi_klad_set_clear_key。
- 解绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_detach。
- 销毁KLAD句柄。调用接口ss_mpi_klad_destroy。
- 去初始化KLAD设备。调用接口ss_mpi_klad_deinit。
注意事项
使用明文KEY传递时,请特别注意以下几点。
- KEYSLOT句柄在配置KLAD之前,必须已通过CIPHER模块创建。
- 传递明文KEY,KLAD类型必须配置为明文KLAD(OT_KLAD_TYPE_CLEARCW)。
ROOTKEY传递
场景说明
当安全方案要求高的场景下采用,ROOTKEY经密钥解混淆、密钥派生后产生,经多级KLAD传递后得到一个真正的工作密钥。工作密钥存储在硬件中,用户不可读取。KLAD将工作密钥传递给一个KEYSLOT。加解密时,加解密引擎取对应KEYSLOT中的KEY用于加解密。
工作流程
ROOTKEY传递开发操作步骤如下:
- KLAD设备初始化。调用接口ss_mpi_klad_init。
- 创建KLAD句柄。调用接口ss_mpi_klad_create。
- 绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_attach。
- 设置KLAD属性。调用接口ss_mpi_klad_set_attr。
- 设置第1~n-1级KLAD密钥信息。调用接口ss_mpi_klad_set_session_key。
- 设置第n级KLAD密钥信息。调用接口ss_mpi_klad_set_content_key。
- 解绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_detach。
- 销毁KLAD句柄。调用接口ss_mpi_klad_destroy。
- 去初始化KLAD设备。调用接口ss_mpi_klad_deinit。
注意事项
使用ROOTKEY传递时,请特别注意以下几点。
- KEYSLOT句柄在配置KLAD之前,必须已通过CIPHER模块创建。
- 传递ROOTKEY,KLAD类型必须配置为通用KLAD(OT_KLAD_TYPE_COMMON)。
密钥派生工具说明
密钥派生工具位于 osdrv/tools/pc/kdf_customer 目录下。使用命令请参考目录下的 readme.txt 文件,下面主要说明 key.ini 文件相关字段的配置。
表 1 key.ini 字段说明
content_key,若使用 128 bit,则派生出的 work_key 也为 128bit;若使用 256 bit,则派生出的 work_key 也为 256bit。 |
|
注:
- 除上述字段外,其他字段无需修改。
- 若 content_key 为128 bit,则work_key 为生成的 out.bin 文件的前16 Bytes;若 content_key 为 256 bit,则 work_key 为生成的整个 out.bin 文件。
API参考
KLAD提供以下API:
- ss_mpi_klad_init:初始化KLAD模块。
- ss_mpi_klad_deinit:去初始化KLAD模块。
- ss_mpi_klad_create:创建一路的KLAD句柄。
- ss_mpi_klad_destroy:销毁已存在的KLAD句柄。
- ss_mpi_klad_attach:绑定KLAD句柄和KEYSLOT句柄。
- ss_mpi_klad_detach:解绑定KLAD句柄和KEYSLOT句柄。
- ss_mpi_klad_set_attr:设置KLAD属性。
- ss_mpi_klad_get_attr:获取KLAD属性。
- ss_mpi_klad_set_session_key:配置第1~n-1级KLAD KEY。
- ss_mpi_klad_set_content_key:配置最后一级KLAD KEY,同时将key传递给KEYSLOT。
- ss_mpi_klad_set_clear_key:配置明文KEY,同时将key传递给KEYSLOT。
ss_mpi_klad_init
【描述】
初始化KLAD模块。
【语法】
【参数】
无。
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
支持多次调用,但需与去初始化成对使用。
【举例】
无。
ss_mpi_klad_deinit
【描述】
去初始化KLAD模块。
【语法】
【参数】
无。
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- 支持多次调用。
- 初始化和去初始化成对使用。
【举例】
无。
ss_mpi_klad_create
【描述】
创建一路的KLAD句柄。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- klad不能为空。
- 使用完通道后,应销毁对应的通道。
- 创建与销毁通道成对使用。
【举例】
无。
ss_mpi_klad_destroy
【描述】
销毁一路KLAD。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD句柄必须已创建。
- 创建与销毁通道成对使用。
【举例】
无。
ss_mpi_klad_attach
【描述】
绑定 KLAD 句柄和 KEYSLOT 句柄。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD、KEYSLOT句柄必须已创建,在句柄未创建的情况下,句柄之间的绑定可能成功,但会导致功能执行失败。
- 绑定和解绑定必须成对使用。
【举例】
无。
ss_mpi_klad_detach
【描述】
解绑定KLAD句柄和KEYSLOT句柄。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD、KEYSLOT句柄必须已创建。
- 绑定和解绑定必须成对使用。
【举例】
无。
ss_mpi_klad_set_attr
【描述】
设置 KLAD 属性。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD句柄必须已创建。
- 可多次调用,每次调用会覆盖之前的属性配置,以最后一次设置的属性为准。
【举例】
无。
ss_mpi_klad_get_attr
【描述】
获取KLAD属性。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
【举例】
无。
ss_mpi_klad_set_session_key
【描述】
配置第1~n-1 级 KLAD KEY。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD句柄必须已创建。
- 该接口不可多次调用,重复调用可能导致密钥配置错误或接口返回失败。
【举例】
无。
ss_mpi_klad_set_content_key
【描述】
配置最后一级 KLAD KEY,同时将key传递给KEYSLOT。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD句柄必须已创建。
- 该接口不可多次调用,重复调用可能导致密钥配置错误或接口返回失败。
- 调用该接口时rootkey不能为0,需要烧写根密钥类型所对应的OTP,参考《安全子系统使用说明》的第2.2.2章节“密钥区域”。
【举例】
无。
ss_mpi_klad_set_clear_key
【描述】
配置明文KEY,同时将key传递给KEYSLOT。
【语法】
【参数】
【返回值】
参见错误码。 |
【需求】
- 头文件:ot_common_klad.h、ss_mpi_klad.h
- 库文件:libss_klad.a、libss_klad.so
【注意】
- KLAD句柄必须已创建。
- 可多次调用,以最后一次设置的属性为准。
【举例】
无。
数据类型
相关数据类型、数据结构定义如下(其他公共数据类型定义请参考ot_type.h):
- ot_klad_rootkey_sel:定义KLAD ROOTKEY选择枚举。
- ot_klad_rootkey_secure:定义KLAD ROOTKEY的静态值枚举。
- ot_klad_rootkey_attr:定义KLAD ROOTKEY属性结构体。
- ot_klad_type:定义KLAD类型枚举。
- ot_klad_cfg:定义KLAD 配置信息结构体。
- ot_klad_crypto_alg:定义KEY在加解密引擎用于哪种算法。
- ot_klad_attr:定义KLAD属性结构体。
- ot_klad_alg_type:定义KLAD算法类型枚举。
- ot_klad_level:定义KLAD层级枚举。
- ot_klad_session_key:定义第1~n-1级KLAD密钥信息结构体。
- ot_klad_content_key:定义第n级KLAD密钥信息结构体。
- ot_klad_clear_key:定义明文密钥信息结构体。
- OT_KLAD_MAX_KEY_LEN:定义KLAD最大密钥长度。
ot_klad_rootkey_sel
【说明】
定义KLAD ROOTKEY选择枚举。
【定义】
/* klad rootkey select */
typedef enum {
OT_KLAD_ROOTKEY_SEL_OEM0 = 0x00,
OT_KLAD_ROOTKEY_SEL_OEM1,
OT_KLAD_ROOTKEY_SEL_OEM2,
OT_KLAD_ROOTKEY_SEL_OEM3,
OT_KLAD_ROOTKEY_SEL_VENDOR,
OT_KLAD_ROOTKEY_SEL_BUTT,
} ot_klad_rootkey_sel;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_rootkey_secure
【说明】
定义KLAD ROOTKEY的静态值枚举。
【定义】
typedef enum {
OT_KLAD_ROOTKEY_SEC_REE = 0x00, /* REE key, TEE CPU can select ree key */
OT_KLAD_ROOTKEY_SEC_TEE, /* TEE key, REE CPU can't select tee key */
OT_KLAD_ROOTKEY_SEC_BUTT,
} ot_klad_rootkey_secure;
【成员】
【注意事项】
- 非安全CPU不能选择TEE密钥静态值。
- 安全CPU能选择REE密钥静态值。
【相关数据类型及接口】
ot_klad_rootkey_attr
【说明】
定义KLAD ROOTKEY属性结构体。
【定义】
/* only OT_KLAD_TYPE_COMMON is valid */
typedef struct {
td_u32 owner_id; /* Derivative material, used for mcipher */
ot_klad_rootkey_sel key_sel; /* common klad route select rootkey */
ot_klad_rootkey_secure key_secure; /* Static value select: for ree key or for tee key */
} ot_klad_rootkey_attr;
【成员】
【注意事项】
仅在KLAD类型为OT_KLAD_TYPE_COMMON时有效。
【相关数据类型及接口】
ot_klad_type
【说明】
定义KLAD类型枚举。
【定义】
/* klad route select */
typedef enum {
OT_KLAD_TYPE_CLEARCW, /* Used for clear key */
OT_KLAD_TYPE_COMMON, /* Used for root key */
OT_KLAD_TYPE_BUTT,
} ot_klad_type;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_cfg
【说明】
定义KLAD 配置信息结构体。
【定义】
/* klad config */
typedef struct {
ot_klad_type klad_type; /* klad route select: common/clear */
ot_klad_rootkey_attr rootkey_attr; /* rootkey attr, OT_KLAD_TYPE_COMMON is valid */
} ot_klad_cfg;
【成员】
【注意事项】
rootkey_attr仅在KLAD类型为OT_KLAD_TYPE_COMMON时有效。
【相关数据类型及接口】
ot_klad_crypto_alg
【说明】
定义KEY在加解密引擎用于哪种算法。
【定义】
/* The key can be used for which algorithm of the crypto engine. */
typedef enum {
OT_KLAD_CRYPTO_ALG_AES = 0,
OT_KLAD_CRYPTO_ALG_SM4,
OT_KLAD_CRYPTO_ALG_BUTT,
} ot_klad_crypto_alg;
【成员】
【注意事项】
Hi3403V100、SS626V100不支持SM4。
【相关数据类型及接口】
ot_klad_attr
【说明】
定义KLAD属性结构体
【定义】
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_alg_type
【说明】
定义KLAD算法类型枚举。
【定义】
/* klad algorithm */
typedef enum {
OT_KLAD_ALG_TYPE_AES = 0,
OT_KLAD_ALG_TYPE_SM4,
OT_KLAD_ALG_TYPE_BUTT,
} ot_klad_alg_type;
【成员】
【注意事项】
Hi3403V100、SS626V100不支持SM4。
【相关数据类型及接口】
ot_klad_level
【说明】
定义KLAD层级枚举。
【定义】
/* klad level */
typedef enum {
OT_KLAD_LEVEL1 = 0,
OT_KLAD_LEVEL2,
OT_KLAD_LEVEL3,
OT_KLAD_LEVEL_BUTT,
} ot_klad_level;
【成员】
【注意事项】
Hi3403V100、SS626V100支持2级KLAD。
【相关数据类型及接口】
ot_klad_session_key
【说明】
定义第1~n-1级KLAD密钥信息结构体。
【定义】
/* session key: set 1~n-1 stage common route klad */
typedef struct {
ot_klad_level level; /* klad level */
ot_klad_alg_type alg; /* klad algorithm */
td_u32 key_size; /* klad key size */
td_u8 key[OT_KLAD_MAX_KEY_LEN]; /* klad key */
} ot_klad_session_key;
【成员】
【注意事项】
- key_size只支持128bits,即16byte。
- 对于Hi3403V100、SS626V100,level只能配置OT_KLAD_LEVEL1。
【相关数据类型及接口】
ot_klad_content_key
【说明】
定义最后一级KLAD密钥信息结构体。
【定义】
/* content key: set n stage common route klad */
typedef struct {
ot_klad_alg_type alg; /* klad algorithm */
ot_klad_crypto_alg crypto_alg; /* allowed target engine algorithm. */
td_u32 key_size; /* klad key size */
td_u8 key[OT_KLAD_MAX_KEY_LEN]; /* klad key */
} ot_klad_content_key;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_clear_key
【说明】
定义明文密钥信息结构体。
【定义】
/* clear key: set clear route klad */
typedef struct {
ot_klad_crypto_alg crypto_alg; /* allowed target engine algorithm. */
td_u32 key_size; /* klad key size */
td_u8 key[OT_KLAD_MAX_KEY_LEN]; /* klad key */
} ot_klad_clear_key;
【成员】
【注意事项】
无。
【相关数据类型及接口】
OT_KLAD_MAX_KEY_LEN
【说明】
定义KLAD最大密钥长度。
【定义】
【注意事项】
无。
【相关数据类型及接口】
- ot_klad_session_key
- ot_klad_content_key
- ot_klad_clear_key
- ss_mpi_klad_set_session_key
- ss_mpi_klad_set_content_key
- ss_mpi_klad_set_clear_key
错误码
KLAD提供的错误码如下所示。
表 1 KLAD模块的错误码